package juc.deadlock;

import lombok.SneakyThrows;

/**
 * 转账时遇到死锁,一代打开注释,边会发生死锁
 */
public class TransferMoney implements Runnable {
    int flag = 1;
    static Account a = new Account(500);
    static Account b = new Account(500);
    static final Object lock = new Object();

    public static void main(String[] args) throws InterruptedException {
        TransferMoney r1 = new TransferMoney();
        TransferMoney r2 = new TransferMoney();
        r1.flag = 1;
        r2.flag = 2;
        Thread t1 = new Thread(r1);
        Thread t2 = new Thread(r2);
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println("a的余额:" + a.balance);
        System.out.println("b的余额:" + b.balance);
    }


    @SneakyThrows
    @Override
    public void run() {
        if (flag == 1) {
            transferMoney(a, b, 200);
        }
        if (flag == 2) {
            transferMoney(b, a, 200);
        }
    }

    private static void transferMoney(Account from, Account to, int amount) throws InterruptedException {
        class Helper {
            public void transfer() {
                if (from.balance - amount < 0) {
                    System.out.println("余额不足,转账失败");
                }
                to.balance += amount;
                from.balance -= amount;
                System.out.println("成功转账" + amount);
            }
        }
        int fromHash = System.identityHashCode(from);
        int toHash = System.identityHashCode(to);
        if (fromHash < toHash) {
            synchronized (from) {
                synchronized (to) {
                    new Helper().transfer();
                }
            }
        } else if (fromHash > toHash) {
            synchronized (to) {
                synchronized (from) {
                    new Helper().transfer();
                }
            }
        } else {
            synchronized (lock) {
                synchronized (from) {
                    synchronized (to) {
                        new Helper().transfer();
                    }
                }
            }
        }
//        synchronized (from) {
//            TimeUnit.SECONDS.sleep(1);
//            synchronized (to) {
//                if (from.balance - amount < 0) {
//                    System.out.println("余额不足,转账失败");
//                }
//                to.balance += amount;
//                from.balance -= amount;
//                System.out.println("成功转账" + amount);
//            }
//        }
    }

    static class Account {
        int balance;

        public Account(int balance) {
            this.balance = balance;
        }
    }

}

